import 'dart:io';

/// 日期时间格式化工具类
/// 专门用于日志记录中的时间格式化
class DateTimeFormatter {
  // 私有构造函数，防止实例化
  DateTimeFormatter._();

  // 常用的时间格式模板
  static const String _defaultLogFormat = 'yyyy-MM-dd HH:mm:ss.SSS';
  static const String _compactLogFormat = 'yyyyMMdd_HHmmss';
  static const String _detailedLogFormat = 'yyyy-MM-dd HH:mm:ss.SSS Z';
  static const String _fileNameFormat = 'yyyy-MM-dd_HH-mm-ss';
  static const String _dateOnlyFormat = 'yyyy-MM-dd';
  static const String _timeOnlyFormat = 'HH:mm:ss';
  static const String _timestampFormat = 'yyyy-MM-ddTHH:mm:ss.SSSZ';

  /// 获取当前时间的默认日志格式
  /// 格式: 2024-01-15 14:30:25.123
  static String now() {
    return format(DateTime.now(), _defaultLogFormat);
  }

  /// 获取当前时间的紧凑格式（用于文件名等）
  /// 格式: 20240115_143025
  static String nowCompact() {
    return format(DateTime.now(), _compactLogFormat);
  }

  /// 获取当前时间的详细格式（包含时区）
  /// 格式: 2024-01-15 14:30:25.123 +0800
  static String nowDetailed() {
    return format(DateTime.now(), _detailedLogFormat);
  }

  /// 获取适合文件名的时间格式
  /// 格式: 2024-01-15_14-30-25
  static String nowForFileName() {
    return format(DateTime.now(), _fileNameFormat);
  }

  /// 获取当前日期
  /// 格式: 2024-01-15
  static String currentDate() {
    return format(DateTime.now(), _dateOnlyFormat);
  }

  /// 获取当前时间
  /// 格式: 14:30:25
  static String currentTime() {
    return format(DateTime.now(), _timeOnlyFormat);
  }

  /// 获取ISO 8601格式的时间戳
  /// 格式: 2024-01-15T14:30:25.123Z
  static String timestamp() {
    return DateTime.now().toUtc().toIso8601String();
  }

  /// 格式化指定的DateTime对象
  ///
  /// [dateTime] 要格式化的DateTime对象
  /// [pattern] 格式化模式，如果为null则使用默认格式
  static String format(DateTime dateTime, [String? pattern]) {
    pattern ??= _defaultLogFormat;
    return _formatDateTime(dateTime, pattern);
  }

  /// 格式化毫秒时间戳
  ///
  /// [milliseconds] 毫秒时间戳
  /// [pattern] 格式化模式
  static String formatMilliseconds(int milliseconds, [String? pattern]) {
    final dateTime = DateTime.fromMillisecondsSinceEpoch(milliseconds);
    return format(dateTime, pattern);
  }

  /// 格式化秒时间戳
  ///
  /// [seconds] 秒时间戳
  /// [pattern] 格式化模式
  static String formatSeconds(int seconds, [String? pattern]) {
    final dateTime = DateTime.fromMillisecondsSinceEpoch(seconds * 1000);
    return format(dateTime, pattern);
  }

  /// 获取相对时间描述（用于日志分析）
  ///
  /// [dateTime] 要比较的时间
  /// [baseTime] 基准时间，默认为当前时间
  static String getRelativeTime(DateTime dateTime, [DateTime? baseTime]) {
    baseTime ??= DateTime.now();
    final difference = baseTime.difference(dateTime);

    if (difference.inDays > 0) {
      return '${difference.inDays}天前';
    } else if (difference.inHours > 0) {
      return '${difference.inHours}小时前';
    } else if (difference.inMinutes > 0) {
      return '${difference.inMinutes}分钟前';
    } else if (difference.inSeconds > 0) {
      return '${difference.inSeconds}秒前';
    } else {
      return '刚刚';
    }
  }

  /// 获取时间间隔描述
  ///
  /// [startTime] 开始时间
  /// [endTime] 结束时间，默认为当前时间
  static String getDuration(DateTime startTime, [DateTime? endTime]) {
    endTime ??= DateTime.now();
    final duration = endTime.difference(startTime);

    if (duration.inDays > 0) {
      return '${duration.inDays}天${duration.inHours % 24}小时${duration.inMinutes % 60}分钟';
    } else if (duration.inHours > 0) {
      return '${duration.inHours}小时${duration.inMinutes % 60}分钟${duration.inSeconds % 60}秒';
    } else if (duration.inMinutes > 0) {
      return '${duration.inMinutes}分钟${duration.inSeconds % 60}秒';
    } else {
      return '${duration.inSeconds}秒${duration.inMilliseconds % 1000}毫秒';
    }
  }

  /// 生成日志文件名
  ///
  /// [prefix] 文件名前缀
  /// [suffix] 文件名后缀，默认为.log
  static String generateLogFileName([String prefix = 'app', String suffix = '.log']) {
    return '${prefix}_${nowForFileName()}$suffix';
  }

  /// 生成按日期分组的日志文件名
  ///
  /// [prefix] 文件名前缀
  /// [suffix] 文件名后缀
  static String generateDailyLogFileName([String prefix = 'app', String suffix = '.log']) {
    return '${prefix}_${currentDate()}$suffix';
  }

  /// 内部格式化方法
  static String _formatDateTime(DateTime dateTime, String pattern) {
    String result = pattern;

    // 年份
    result = result.replaceAll('yyyy', dateTime.year.toString().padLeft(4, '0'));
    result = result.replaceAll('yy', (dateTime.year % 100).toString().padLeft(2, '0'));

    // 月份
    result = result.replaceAll('MM', dateTime.month.toString().padLeft(2, '0'));
    result = result.replaceAll('M', dateTime.month.toString());

    // 日期
    result = result.replaceAll('dd', dateTime.day.toString().padLeft(2, '0'));
    result = result.replaceAll('d', dateTime.day.toString());

    // 小时
    result = result.replaceAll('HH', dateTime.hour.toString().padLeft(2, '0'));
    result = result.replaceAll('H', dateTime.hour.toString());

    // 分钟
    result = result.replaceAll('mm', dateTime.minute.toString().padLeft(2, '0'));
    result = result.replaceAll('m', dateTime.minute.toString());

    // 秒钟
    result = result.replaceAll('ss', dateTime.second.toString().padLeft(2, '0'));
    result = result.replaceAll('s', dateTime.second.toString());

    // 毫秒
    result = result.replaceAll('SSS', dateTime.millisecond.toString().padLeft(3, '0'));
    result = result.replaceAll('SS', (dateTime.millisecond ~/ 10).toString().padLeft(2, '0'));
    result = result.replaceAll('S', (dateTime.millisecond ~/ 100).toString());

    // 时区
    final timeZoneOffset = dateTime.timeZoneOffset;
    final offsetHours = timeZoneOffset.inHours;
    final offsetMinutes = timeZoneOffset.inMinutes.remainder(60);
    final timeZoneString = '${offsetHours >= 0 ? '+' : ''}${offsetHours.toString().padLeft(2, '0')}${offsetMinutes.toString().padLeft(2, '0')}';
    result = result.replaceAll('Z', timeZoneString);

    return result;
  }

  /// 解析时间字符串（常用格式）
  ///
  /// [timeString] 时间字符串
  /// [pattern] 解析模式，如果为null则尝试常用格式
  static DateTime? parseTime(String timeString, [String? pattern]) {
    try {
      if (pattern != null) {
        // 简单的解析逻辑，实际项目中可能需要更复杂的解析
        return DateTime.parse(timeString);
      }

      // 尝试常用格式
      final patterns = [
        _defaultLogFormat,
        _timestampFormat,
        _dateOnlyFormat,
        'yyyy-MM-dd HH:mm:ss',
      ];

      for (final p in patterns) {
        try {
          return DateTime.parse(timeString);
        } catch (e) {
          continue;
        }
      }

      return null;
    } catch (e) {
      return null;
    }
  }

  /// 判断是否为今天
  static bool isToday(DateTime dateTime) {
    final now = DateTime.now();
    return dateTime.year == now.year &&
        dateTime.month == now.month &&
        dateTime.day == now.day;
  }

  /// 判断是否为昨天
  static bool isYesterday(DateTime dateTime) {
    final yesterday = DateTime.now().subtract(const Duration(days: 1));
    return dateTime.year == yesterday.year &&
        dateTime.month == yesterday.month &&
        dateTime.day == yesterday.day;
  }

  /// 获取友好的时间显示
  ///
  /// [dateTime] 要格式化的时间
  /// [showRelative] 是否显示相对时间
  static String getFriendlyTime(DateTime dateTime, {bool showRelative = true}) {
    if (showRelative) {
      if (isToday(dateTime)) {
        return '今天 ${format(dateTime, _timeOnlyFormat)}';
      } else if (isYesterday(dateTime)) {
        return '昨天 ${format(dateTime, _timeOnlyFormat)}';
      } else {
        final diff = DateTime.now().difference(dateTime).inDays;
        if (diff < 7) {
          return '${diff}天前 ${format(dateTime, _timeOnlyFormat)}';
        }
      }
    }

    return format(dateTime, _defaultLogFormat);
  }
}